import os
import subprocess
import asyncio
import sys
import random
import aiohttp
from colorama import init, Fore, Style
from common import modules_info, list_modules, run_module, run_path_scanner, run_subdomain_enumeration, list_modules_cn
# Fore.BLACK 黑色
# Fore.RED 红色
# Fore.GREEN 绿色
# Fore.YELLOW 黄色
# Fore.BLUE 蓝色
# Fore.MAGENTA 品红
# Fore.CYAN 蓝绿色
# Fore.WHITE 白色
# Fore.RESET 重置
# Style.RESET_ALL 风格全部重置
install_dir = os.path.dirname(os.path.realpath(__file__))
os.chdir(install_dir)
sys.path.append(install_dir)
current_module = None
options = {}

def print_random_txt():
    random_number = random.randint(1, 4)
    file_name = "theme/"+f"{random_number}.txt"
    
    try:
        with open(file_name, 'r') as file:
            print(Fore.YELLOW+file.read()+Style.RESET_ALL)
    except FileNotFoundError:
        print(f"[-]Error: File {file_name} not found.")
def main():
    print(Fore.BLUE+"[*] Open Source Project:"+Style.RESET_ALL)
    print(Fore.CYAN+"https://github.com/sansjtw/Hoho_Framework"+Style.RESET_ALL)
    print(Fore.CYAN+"https://gitee.com/sansjtw/Hoho_Framework"+Style.RESET_ALL)
    print(Style.RESET_ALL+Fore.GREEN + "\nWelcome to Hoho Framework 1.0"+ Style.RESET_ALL)
    print(Style.RESET_ALL+Fore.GREEN + "[*] Hoho Framework v1.0 beta"+ Style.RESET_ALL)
    print(Style.RESET_ALL+Fore.GREEN + "[*] Available modules: 6"+ Style.RESET_ALL)
    print(Style.RESET_ALL+Fore.GREEN + "[*] Available features: 25"+ Style.RESET_ALL)
    print(Style.RESET_ALL+Fore.GREEN + "[*] To view the help, you can use the `help` command."+ Style.RESET_ALL)
    print(Style.RESET_ALL+Fore.MAGENTA + "\n[*]Author's blog:\nhttps://sansjtw.xyz\nhttps://sansjtw.github.io/\n"+Style.RESET_ALL)
    while True:
        try:
            command = input(Style.RESET_ALL+"hoho("+Fore.MAGENTA+f"{current_module}"+Style.RESET_ALL+")> " if current_module else "hoho > ").strip()
            if command == 'exit':
                break
            elif command == 'ls':
                list_files()
            elif command == 'help':
                show_help()
            elif command == 'list':
                list_modules()
            elif command.startswith('use '):
                _, module_path = command.split(maxsplit=1)
                use_module(module_path)
            elif command.startswith('set '):
                set_option(command)
            elif command == 'options':
                show_options()
            elif command == 'run':
                run_module(current_module, options)
            elif command.startswith('help -l'):
                module_help()
            elif command == 'cancel':
                cancel_module()
            elif command == 'list -c':
                list_modules_cn()
            elif command == 'help -c':
                show_help_cn()
            else:
                print(Style.RESET_ALL+Fore.RED +f"[-] Unknown command: {command}"+ Style.RESET_ALL)
        except KeyboardInterrupt:
            print(Style.RESET_ALL+Fore.YELLOW +"\nExiting Hoho Framework." + Style.RESET_ALL)
            break
            
print_random_txt()

def list_files():
    subprocess.run(['ls', '-la'])

def show_help():
    print(Style.RESET_ALL+Fore.CYAN +"""
Hoho Framework commands:
  ls                 - List files in the current directory (similar to Linux command)
  help               - Show this help message
  help -l            - Show help for the current module (after using a module with 'use')
  help -c            - Display help messages in Chinese language
  list               - List all available modules
  list -c            - List Chinese languages of all available modules
  use <module_path>  - Use a specified module
  set <key> <value>  - Set a parameter for the current module
  options            - Show the current parameters for the module
  run                - Run the selected module with the set parameters
  cancel             - Cancel the selection of the current module
  exit               - Exit the Hoho Framework
"""+ Style.RESET_ALL)
# Fore.CYAN 蓝绿色

def show_help_cn():
    print(Style.RESET_ALL+Fore.CYAN +"""
Hoho Framework控制台命令：
  ls                 - 显示当前目录中的文件列表（类似于Linux命令）
  help               - 显示此帮助信息
  help -l            - 显示当前模块的帮助信息（在使用“use”命令后）
  help -c            - 以中文显示帮助信息
  list               - 列出所有可用的模块
  list -c            - 列出所有可用模块的中文名称
  use <module_path>  - 使用指定的模块
  set <key> <value>  - 为当前模块设置参数
  options            - 显示当前模块的参数
  run                - 使用设置的参数运行选定的模块
  cancel             - 取消当前模块的选择
  exit               - 退出Hoho Framework
"""+ Style.RESET_ALL)

def use_module(module_path):
    global current_module
    if module_path in modules_info:
        current_module = module_path
        print(Style.RESET_ALL+Fore.GREEN +f"Module {module_path} selected."+ Style.RESET_ALL)
        # Fore.GREEN 绿色的
    else:
        print(Style.RESET_ALL+Fore.RED +f"Module {module_path} not found."+ Style.RESET_ALL)

def set_option(command):
    if current_module == "Information_gathering/python_whois":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Information_gathering/website_fingerprint":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Network_sniffing/arp_spoof":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Network_sniffing/dhcp_spoofing":
        print("No specific options to set for this module.")
    elif current_module == "Network_sniffing/dns_spoofing":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        if key == "choice" and value not in ["1", "2"]:
            print("Invalid choice. Choose 1 or 2.")
            return
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Network_sniffing/icmp_redirect":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Network_sniffing/mac_flooding":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Network_sniffing/Wi-Fi_Sniffing":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Port_scanning/Port_scanning":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Port_scanning/python-nmap":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Port_scanning/null_scan":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Port_scanning/fin_scan":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Port_scanning/xmas_scan":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Port_scanning/tcp_connect_scan":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Port_scanning/syn_scan":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Password_Cracking/brute_force_zip":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Password_Cracking/Dictionary_Attack":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Network_scanning/Arp_scanning":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Network_scanning/path_scanner":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Network_scanning/Subdomain_enumeration":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Information_gathering/Host_discovery":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    elif current_module == "Social_engineering/QR_Visitor_Tracker":
        parts = command.split(maxsplit=2)
        if len(parts) < 3:
            print(Style.RESET_ALL+Fore.RED +"[-]Error: Missing key or value. Usage: set <key> <value>"+ Style.RESET_ALL)
            return
        _, key, value = parts
        options[key] = value
        print(Style.RESET_ALL+Fore.GREEN +f"Set {key} to {value}"+ Style.RESET_ALL)
    else:
        print(Style.RESET_ALL+Fore.RED +"[-] Unknown module."+ Style.RESET_ALL)
        
def show_options():
    print("Current options:")
    for key, value in options.items():
        print(f"{key}: {value}")

def module_help():
    if current_module == "Password_Cracking/brute_force_zip":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Password_Cracking/brute_force_zip options:
  set zip_file_path <path>     - Path to the ZIP file
  set charset <characters>     - Character set to use (default: abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ)
  set max_length <length>      - Maximum length of the password (default: 4)
""")
    elif current_module == "Password_Cracking/Dictionary_Attack":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Password_Cracking/Dictionary_Attack options:
  set zip_file_path <path>           - Path to the ZIP file
  set dictionary_file_path <path>    - Path to the dictionary file
""")
    elif current_module == "Social_engineering/visitor_logger":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Social_engineering/visitor_logger options:
  No options available. Just run the module to start the visitor logger.
""")
    elif current_module == "Network_scanning/Arp_scanning":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Network_scanning/Arp_scanning options:
  set ip_range <range>  - IP range to scan (default: 192.168.0.1/24)
""")
    elif current_module == "Network_scanning/path_scanner":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Network_scanning/path_scanner options:
  set base_url <url>           - Base URL to scan (e.g., http://example.com)
  set wordlist_file <path>     - Path to the wordlist file
""")
    elif current_module == "Network_scanning/Subdomain_enumeration":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Network_scanning/Subdomain_enumeration options:
  set base_url <url>           - Base URL to scan (e.g., example.com)
  set wordlist_file <path>     - Path to the wordlist file
""")
    elif current_module == "Information_gathering/Host_discovery":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Information_gathering/Host_discovery options:
  set network_address <address> - Network address to scan (e.g., 192.168.1.0/24)
""")
    elif current_module == "Information_gathering/information_gathering":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Information_gathering/information_gathering options:
  No options available. Just run the module to start gathering information.
""")
    elif current_module == "Information_gathering/iot_device_scanner":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Information_gathering/iot_device_scanner options:
  set network_range <range>  - Network range to scan (e.g., 192.168.1.0/24)
""")
    elif current_module == "Information_gathering/python_whois":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Information_gathering/python_whois options:
  set domain <domain>  - Domain to query WHOIS information for
""")
    elif current_module == "Information_gathering/website_fingerprint":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Information_gathering/website_fingerprint options:
  set url <url>  - URL of the website to fingerprint (e.g., http://example.com)
""")
    elif current_module == "Network_sniffing/arp_spoof":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Network_sniffing/arp_spoof options:
  set target_ip <ip>     - Target IP address for ARP spoofing
  set gateway_ip <ip>    - Gateway IP address for ARP spoofing
""")
    elif current_module == "Network_sniffing/dhcp_spoofing":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Network_sniffing/dhcp_spoofing options:
  set target_ip <ip>      - Target IP address for the DHCP spoofing attack
  set gateway_ip <ip>     - Gateway IP address for the DHCP spoofing attack
""")
    elif current_module == "Network_sniffing/dns_spoofing":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Network_sniffing/dns_spoofing options:
  set choice <option>          - Select DNS spoofing type (1 for IP only, 2 for IP + domain)
  set spoofed_ip <ip>          - Specify the spoofed IP address
  set target_domain <domain>   - Specify the target domain (for IP + domain spoofing)
""")
    elif current_module == "Network_sniffing/icmp_redirect":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Network_sniffing/icmp_redirect options:
  set router_ip <ip>       - IP address of the router
  set target_ip <ip>       - IP address of the target host
  set redirect_ip <ip>     - IP address to redirect to
""")
    elif current_module == "Network_sniffing/mac_flooding":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Network_sniffing/mac_flooding options:
  set target_ip <ip>  - IP address of the target host
""")
    elif current_module == "Network_sniffing/sniffing_tool":
        print("run with the run command.")
    elif current_module == "Network_sniffing/Wi-Fi_Sniffing":
        print("No specific options to set for this module.")  # Wi-Fi Sniffing 模块不需要设置特定选项
    elif current_module == "Port_scanning/Port_scanning":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Port_scanning/Port_scanning options:
  set host <host>           - Host to scan (e.g., example.com)
  set port_start <port>     - Start port number (e.g., 1)
  set port_end <port>       - End port number (e.g., 1024)
""")
    elif current_module == "Port_scanning/python-nmap":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Port_scanning/python-nmap options:
  set host <host>           - Host to scan (e.g., example.com)
  set start_port <port>     - Start port number (e.g., 1)
  set end_port <port>       - End port number (e.g., 1024)
""")
    elif current_module == "Port_scanning/null_scan":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Port_scanning/python-nmap options:
  set ip <ip>           - Enter the ip address (e.g., 127.0.0.1)
  set port <port>     - inport (e.g., 8080)
""")
    elif current_module == "Port_scanning/fin_scan":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Port_scanning/fin_scan options:
  set ip <ip>           - Enter the ip address (e.g., 127.0.0.1)
  set start_port <port>     - Start port number (e.g., 1)
  set end_port <port>       - End port number (e.g., 1024)
""")
    elif current_module == "Port_scanning/xmas_scan":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Port_scanning/xmas_scan options:
  set ip <ip>           - Enter the ip address (e.g., 127.0.0.1)
  set port <port>     - Start port number (e.g., 8080)
""")
    elif current_module == "Port_scanning/tcp_connect_scan":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Port_scanning/tcp_connect_scan options:
  set ip <ip>           - Enter the ip address (e.g., 127.0.0.1)
  set start_port <port>     - Start port number (e.g., 1)
  set end_port <port>       - End port number (e.g., 1024)
""")
    elif current_module == "Port_scanning/syn_scan":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Port_scanning/tcp_connect_scan options:
  set ip <ip>           - Enter the ip address (e.g., 127.0.0.1)
  set start_port <port>     - Start port number (e.g., 1)
  set end_port <port>       - End port number (e.g., 1024)
""")
    elif current_module == "Social_engineering/QR_Visitor_Tracker":
        print(Style.RESET_ALL+Fore.CYAN+"""
Module Port_scanning/tcp_connect_scan options:
  set server <server_address>      - Enter the server address (e,g., 127.0.0.1)
  set port <serve_port>            - Enter the server port (e,g., 5000)
  
  Visit http://<server_address>/generate_qr/<visitor_name> to generate a QR code for the visitor. After the visitor scans the QR code, the information will be automatically logged to the terminal and a file.
""")
    else:
        print(Style.RESET_ALL+Fore.RED +"[-] Unknown module."+ Style.RESET_ALL)
        
def cancel_module():
    global current_module, options
    current_module = None
    options = {}
    print(Fore.GREEN+"[*] Cancelled the selection of the current module."+Style.RESET_ALL)

if __name__ == "__main__":
    main()
